#pragma once

#include "ECS.h"

namespace ECS
{
	/// A factory to create and initialize components with a template data
	class IComponentTemplate
	{
	public: 
		virtual Component* create() = 0;
		virtual void afterInit(Component* component) {}
	};

	namespace impl
	{
		/// @tparam TDef class of component definition
		/// @tparam TComponent class of component
		template <class TDef, class TComponent>
		class ComponentTemplate : public IComponentTemplate
		{
		public:
			TDef* definition;

			virtual Component* create() override
			{
				TComponent* component = new TComponent();
				component->initWithDef(definition);

				return component;
			}
		};
	}

	/// @class	AssemblyTemplate
	///
	/// Use this class to initialize objects with a given template.
	/// 		
	/// @details Assembly template is a description of all components and it's properties in an assembly.
	/// 		 You can use the same template for different objects.
	class AssemblyTemplate
	{
	public:

		/// @brief	Applies template to an assembly
		///
		/// @param [in,out]	assembly	Assembly to apply template. Can not be null.
		void apply(Assembly* assembly);

		/// @brief	Adds a component template.
		///
		/// @param [in]	item	Component template. Can not be null.
		void addComponent( IComponentTemplate* item );
	protected:
		std::vector<IComponentTemplate*> _components;
	};
}
